<template>
  <el-tabs v-model="controlActiveName" @tab-click="controlTabHandle">
    <el-tab-pane
      v-for="item in controlOption"
      :label="item.label"
      :name="item.key"
      :key="item.key"
    >
      <div class="children-box">
        <template
          v-if="Array.isArray(item.children) && item.children.length > 0"
        >
          <el-tabs v-model="detailsActiveName">
            <el-tab-pane
              v-for="innerItem in item.children"
              :label="innerItem.label"
              :name="innerItem.key"
              :key="innerItem.key"
            >
              <el-empty v-if="!innerItem.value" description="暂无数据" />
              <pre v-else>
                <code class="hljs" v-html="highlightedCode(innerItem)" />
              </pre>
            </el-tab-pane>
          </el-tabs>
        </template>
        <template v-if="item.value">
          <el-empty v-if="!item.value" description="暂无数据" />
          <pre v-else>
            <code class="hljs" v-html="highlightedCode(item)" />
          </pre>
        </template>
        <el-empty
          v-if="
            !item.value &&
              !(Array.isArray(item.children) && item.children.length > 0)
          "
          description="暂无数据"
        />
      </div>
    </el-tab-pane>
  </el-tabs>
</template>

<script>
import request from "@/utils/request";
import hljs from "highlight.js/lib/highlight";
import "highlight.js/styles/github-gist.css";
hljs.registerLanguage("java", require("highlight.js/lib/languages/java"));
hljs.registerLanguage("xml", require("highlight.js/lib/languages/xml"));
hljs.registerLanguage("html", require("highlight.js/lib/languages/xml"));
hljs.registerLanguage("vue", require("highlight.js/lib/languages/xml"));
hljs.registerLanguage(
  "javascript",
  require("highlight.js/lib/languages/javascript")
);
hljs.registerLanguage("sql", require("highlight.js/lib/languages/sql"));

export default {
  name: "GenPreview",
  props: {
    previewTableId: {
      type: String,
      require: true
    }
  },
  data() {
    return {
      controlActiveName: "backEnd",
      detailsActiveName: "entity",
      controlOption: [
        {
          key: "backEnd",
          label: "后端",
          children: []
        },
        {
          key: "nonSep",
          label: "非前后端分离",
          children: []
        },
        {
          key: "sep",
          label: "前后端分离",
          vmKey: "vue",
          children: []
        },
        { key: "sql", label: "SQL" }
      ]
    };
  },
  created() {
    this.loadPreviewData(this.previewTableId);
  },
  methods: {
    async loadPreviewData(tableId) {
      const loading = this.$loading({
        lock: true,
        text: "数据加载中",
        spinner: "el-icon-loading",
        background: "rgba(0, 0, 0, 0.7)"
      });
      try {
        const res = await request({
          url: "/tool/gen/preview/" + tableId,
          method: "get"
        });
        const { parameters, success } = res;
        if (success) {
          if (parameters && parameters.data) {
            this.buildControlOptionValue(parameters.data, this.controlOption);
          }
        }
        loading.close();
      } catch (err) {
        loading.close();
      }
    },
    buildControlOptionValue(vmDataObj, option) {
      for (let key in vmDataObj) {
        const k = key.substring(key.lastIndexOf("/") + 1, key.indexOf("."));
        const v = key.substring(key.lastIndexOf("/") + 1, key.lastIndexOf("."));
        if (key.indexOf("vm/java") != -1) {
          this.setOptionChildren(option, "backEnd", k, v, key, vmDataObj[key]);
        } else if (key === "vm/xml/mapper.xml.vm") {
          this.setOptionChildren(
            option,
            "backEnd",
            "mapperXml",
            v,
            key,
            vmDataObj[key]
          );
        } else if (key.indexOf("vm/html") != -1) {
          this.setOptionChildren(option, "nonSep", k, v, key, vmDataObj[key]);
        } else if (key.indexOf("vm/vue") != -1) {
          this.setOptionChildren(option, "sep", k, v, key, vmDataObj[key]);
        } else if (key.indexOf("vm/sql") != -1) {
          this.setOptionChildren(option, "sql", k, v, key, vmDataObj[key]);
        }
      }
    },
    setOptionChildren(
      option,
      parentKey,
      childKey,
      childLabel,
      childVMKey,
      childValue
    ) {
      option.forEach(item => {
        if (item.key === parentKey) {
          if (item.key === "sql") {
            item.value = childValue;
            item.vmKey = childVMKey;
          } else {
            item.children.push({
              key: childKey,
              label: childLabel,
              value: childValue,
              vmKey: childVMKey
            });
          }
        }
      });
    },
    controlTabHandle(tab) {
      const findOptions = this.controlOption.filter(item => {
        return item.key === tab.name;
      });
      if (findOptions.length > 0) {
        const optionChildren = findOptions[0].children;
        if (Array.isArray(optionChildren) && optionChildren.length > 0) {
          if (optionChildren[0].key !== this.detailsActiveName) {
            this.detailsActiveName = optionChildren[0].key;
          }
        } else {
          if (findOptions[0].key !== this.detailsActiveName) {
            this.detailsActiveName = findOptions[0].key;
          }
        }
      }
    },
    highlightedCode(item) {
      const { vmKey, value } = item;
      const vmName = vmKey.substring(
        vmKey.lastIndexOf("/") + 1,
        vmKey.indexOf(".vm")
      );
      const language = vmName.substring(vmName.indexOf(".") + 1, vmName.length);
      const result = hljs.highlight(language, value || "", true);
      return result.value || "&nbsp;";
    }
  }
};
</script>

<style scoped lang="scss">
.children-box {
  margin-left: 20px;
  margin-right: 20px;
  pre {
    display: flex;
    flex-flow: column nowrap;
    margin: 0;
    padding: 0;
    border: none;
  }
}
</style>
